package controll

import (
	"encoding/json"
	"fmt"
	"haodayizhi/global"
	"haodayizhi/model"
	mtype "haodayizhi/types"
	util "haodayizhi/utils"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
)

// 获取通知列表
func GetNoticeList(c *gin.Context) {
	listParams := mtype.NoticeListParams{}

	response := mtype.ResponseType{
		Code:    http.StatusOK,
		Message: "Success",
		Result:  map[string]string{},
	}
	err := c.ShouldBind(&listParams)
	if err != nil {
		util.LogMessage(util.LogTypeError, fmt.Sprintf("Failed to get product list params: %v", err))
		util.CommonErrorHandler(c, "Failed to get product list params", http.StatusBadRequest, nil, err)
		return
	}
	limit, err := strconv.Atoi(c.Query("limit"))
	if err != nil {
		util.LogMessage(util.LogTypeError, fmt.Sprintf("Failed to get product list params: %v", err))
		util.CommonErrorHandler(c, "Failed to get product list params", http.StatusBadRequest, nil, err)
		return
	}
	page, err := strconv.Atoi(c.Query("page"))
	if err != nil {
		util.LogMessage(util.LogTypeError, fmt.Sprintf("Failed to get product list params: %v", err))
		util.CommonErrorHandler(c, "Failed to get product list params", http.StatusBadRequest, nil, err)
		return
	}
	listParams.Page = page
	listParams.Limit = limit
	startTime := c.Query("start_time")
	endTime := c.Query("end_time")
	listParams.StartTime = startTime
	listParams.EndTime = endTime

	// 获取当前用户ID
	tokenConfig := mtype.TokenConfig{}
	headInfo, exists := c.Get(global.LOG_USER)
	headInfoByte, err := json.Marshal(headInfo)
	if err != nil {
		util.LogMessage(util.LogTypeError, fmt.Sprintf("Failed to get user info: %v", err))
		util.CommonErrorHandler(c, "Failed to get user info", http.StatusInternalServerError, nil, err)
		return
	}
	err = json.Unmarshal(headInfoByte, &tokenConfig)
	if err != nil {
		util.LogMessage(util.LogTypeError, fmt.Sprintf("Failed to get user info: %v", err))
		util.CommonErrorHandler(c, "Failed to get user info", http.StatusInternalServerError, nil, err)
		return
	}
	if !exists {
		util.LogMessage(util.LogTypeError, fmt.Sprintf("Failed to get user info: %v", exists))
		util.CommonErrorHandler(c, "Failed to get user info", http.StatusInternalServerError, nil, err)
		return
	}

	// 获取通知列表
	noticeRecipientsModel := model.NotificationRecipient{}
	noticeRecipients, total, err := noticeRecipientsModel.GetNotificationRecipientByUID(int64(tokenConfig.UserID), listParams.Page, listParams.Limit)
	if err != nil {
		util.LogMessage(util.LogTypeError, fmt.Sprintf("Failed to get notification recipients: %v", err))
		util.CommonErrorHandler(c, "Failed to get notification recipients", http.StatusInternalServerError, nil, err)
		return
	}

	// 通过接收到的通知，获取到通知内容
	//拿出通知ID
	var noticeIDs []int64
	for _, v := range noticeRecipients {
		noticeIDs = append(noticeIDs, v.NotificationID)
	}
	// 查询到通知内容
	noticeModel := model.Notification{}
	notices, err := noticeModel.GetNotificationsByIDs(noticeIDs)
	if err != nil {
		util.LogMessage(util.LogTypeError, fmt.Sprintf("Failed to get notifications: %v", err))
		util.CommonErrorHandler(c, "Failed to get notifications", http.StatusInternalServerError, nil, err)
		return
	}
	// 组装返回数据
	type NoticeList struct {
		model.Notification
		Status   string `json:"status"`
		ReadTime string `json:"read_time"`
	}

	var noticeLists []NoticeList // 使用切片来存储结果

	// 遍历通知列表和接收者列表
	for _, v := range notices {
		var status string
		var readTime string

		for _, noticeRecipient := range noticeRecipients {
			if noticeRecipient.NotificationID == v.ID {
				status = noticeRecipient.Status
				if !noticeRecipient.ReadTime.IsZero() {
					readTime = noticeRecipient.ReadTime.Format("2006-01-02 15:04:05")
				}
				break // 一旦找到匹配的接收者，可以跳出内层循环
			}
		}

		// 组装数据
		noticeList := NoticeList{
			Notification: v,
			Status:       status,
			ReadTime:     readTime,
		}

		noticeLists = append(noticeLists, noticeList) // 将结果追加到切片中
	}

	response.Result = mtype.ProductList{
		Total: total,
		List:  noticeLists,
	}
	c.JSON(http.StatusOK, response)
}

// 通知详情
func GetNotificationDetail(c *gin.Context) {
	response := mtype.ResponseType{
		Code:    200,
		Message: "Success",
	}
	notificationIDStr := c.Query("n_id")

	notificationID, err := strconv.Atoi(notificationIDStr)
	if err != nil || notificationID <= 0 {
		util.CommonErrorHandler(c, "Invalid notification ID", http.StatusBadRequest, nil, err)
		return
	}
	// 获取通知内容
	noticeModel := model.Notification{}
	notice, err := noticeModel.GetNotificationByID(int64(notificationID))
	if err != nil {
		util.LogMessage(util.LogTypeError, fmt.Sprintf("Failed to get notification: %v", err))
		util.CommonErrorHandler(c, "Failed to get notification", http.StatusInternalServerError, nil, err)
		return
	}
	response.Result = notice
	c.JSON(http.StatusOK, response)
}

// 标记通知为已读
func MarkNotificationAsRead(c *gin.Context) {
	notificationIDStr := c.Query("n_id")

	tokenConfig, err := util.GetTokenInfo(c)
	if err != nil {
		util.CommonErrorHandler(c, "Invalid token", http.StatusUnauthorized, nil, err)
		return
	}

	notificationID, err := strconv.Atoi(notificationIDStr)
	if err != nil || notificationID <= 0 {
		util.CommonErrorHandler(c, "Invalid notification ID", http.StatusBadRequest, nil, err)
		return
	}

	// 更新通知状态为已读
	err = model.UpdateNotificationRecipientStatus(int64(notificationID), int64(tokenConfig.UserID), "read")
	if err != nil {
		util.CommonErrorHandler(c, "Error updating notification status", http.StatusInternalServerError, nil, err)
		return
	}

	c.JSON(http.StatusOK, mtype.ResponseType{
		Code:    http.StatusOK,
		Message: "Notification marked as read",
	})
}

// 发送通知消息
func SendNoticeInfo(c *gin.Context) {
	tokenConfig, err := util.GetTokenInfo(c)
	if err != nil {
		util.CommonErrorHandler(c, "Invalid token", http.StatusUnauthorized, nil, err)
		return
	}
	response := mtype.ResponseType{
		Code:    200,
		Message: "Success",
	}
	// 获取参数
	noticeParams := struct {
		model.Notification
		RecipientUIDs interface{} `json:"recipientUIDs" from:"recipientUIDs"`
	}{}

	err = c.ShouldBind(&noticeParams)
	if err != nil {
		util.CommonErrorHandler(c, "Invalid parameters", http.StatusBadRequest, nil, err)
		return
	}

	// 发送通知
	noticeModel := model.Notification{}
	noticeModel.SenderEmail = tokenConfig.Email
	noticeModel.SenderUID = tokenConfig.UserID
	noticeModel.NoticeTime = global.MTime{}.Now()
	noticeModel.Content = noticeParams.Content
	noticeModel.Title = noticeParams.Title
	noticeModel.NoticeType = noticeParams.NoticeType
	noticeModel.RecipientType = noticeParams.RecipientType
	noticeModel.SenderUsername = noticeParams.SenderUsername
	fmt.Println(noticeModel)
	err = noticeModel.CreateNotification()
	if err != nil {
		util.LogMessage(util.LogTypeError, fmt.Sprintf("Failed to send notification: %v", err))
		util.CommonErrorHandler(c, "Failed to send notification", http.StatusBadGateway, nil, err)
		return
	}
	response.Result = "Notification sent"

	c.JSON(http.StatusOK, response)

	go func(noticeInfo struct {
		model.Notification
		RecipientUIDs interface{} `json:"recipientUIDs" from:"recipientUIDs"`
	}, n_id int64) {
		if noticeInfo.RecipientType == "all" {
			go SendNoticeToAll(n_id)
		} else {
			uids := []int64{}
			err := util.TransTypeToMyType(noticeInfo.RecipientUIDs, &uids)
			if err != nil {
				util.LogMessage(util.LogTypeError, fmt.Sprintf("Failed to send notification: %v", err))
			}
			go SendNoticeToSpecific(noticeModel.ID, uids)
		}
	}(noticeParams, noticeModel.ID)
}

// 异步处理发送通知给所有员工
func SendNoticeToAll(noticeID int64) {
	// 查询所有员工
	userModel := model.User{}
	IDS, err := userModel.GetAllUserIDs()
	if err != nil {
		util.LogMessage(util.LogTypeError, fmt.Sprintf("Failed to get all users: %v", err))
	}
	// 创建通知接收人
	err = model.CreateAllNotificationRecipient(IDS, noticeID)
	if err != nil {
		util.LogMessage(util.LogTypeError, fmt.Sprintf("Failed to create notification recipient: %v", err))
	}

}

// 发送通知给指定用户
func SendNoticeToSpecific(noticeID int64, recipientUIDs []int64) {
	// 创建通知接收人
	err := model.CreateAllNotificationRecipient(recipientUIDs, noticeID)
	if err != nil {
		util.LogMessage(util.LogTypeError, fmt.Sprintf("Failed to create notification recipient: %v", err))
	}
}
